/*
Copyright (c) 2008, Daniel Guerrero Martínez
All rights reserved.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
	-Redistributions of source code must retain the above copyright notice, this
	list of conditions and the following disclaimer.
	-Redistributions in binary form must reproduce the above copyright notice,
	this list of conditions and the following disclaimer in the documentation
	and/or other materials provided with the distribution.
	-Neither the name of the <ORGANIZATION> nor the names of its contributors may
	be used to endorse or promote products derived from this software without
	specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
 */

package Imagenes;

import java.awt.BasicStroke;
import javax.swing.JPanel;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.util.ArrayList;


public class Lienzo extends JPanel {
  BorderLayout borderLayout1 = new BorderLayout();
  ArrayList L ;
  Point p=null,p2=null;
  int forma = 0;
  BarraHerramientas creador = null;
  java.awt.geom.Rectangle2D seleccion =null ;
  int indice_seleccion = 0, x, y;
  boolean control_curva = false,control_curva2 = false;
  BufferedImage buffer = null;
  BufferedImage original = null;


  public Lienzo(BarraHerramientas m, BufferedImage fondo) {
    try {
      jbInit();
      creador = m;
      L = new ArrayList();
      original = fondo;
      buffer = new java.awt.image.BufferedImage(original.getWidth(), original.getHeight(), java.awt.image.BufferedImage.TYPE_INT_RGB);
      buffer.getGraphics().drawImage(original, 0, 0, null);
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }
  }

    @Override
  public void paint(Graphics G){
    super.paint(G);
    ((Graphics2D)G).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    G.drawImage(buffer, 0, 0, this);
    if(L.size() != 0) ((Figura)L.get(0)).Dibujar((Graphics2D)G);
    if (seleccion != null){
        float dash[]= {3.0F,3.0F};
        ((Graphics2D)G).setStroke(new java.awt.BasicStroke(3, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL, 10,dash, 0F));
        ((Graphics2D)G).setColor(Color.BLACK);
        ((Graphics2D)G).draw(seleccion);
    }
  }

  public void actualizar_paint(){
      Graphics2D G = (Graphics2D) buffer.getGraphics();
      G.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
      G.drawImage(original, 0, 0, null);
      for(int i=L.size()-1;i>=0;i--){
        ((Figura)L.get(i)).Dibujar(G);
      }
      repaint();
  }

  void jbInit() throws Exception {
    this.addMouseMotionListener(new Lienzo_this_mouseMotionAdapter(this));
    this.addMouseListener(new Lienzo_this_mouseAdapter(this));
    this.setLayout(borderLayout1);
  }

  void this_mouseClicked(MouseEvent e) {
        if(creador.pincel == Figura.TIPO_TEXTO){
            boolean selec = false;
            for(int i=0;i<L.size() && selec == false;i++){
              if(((Figura)L.get(i)).es_figura(e.getPoint())){
                  if(Figura.TIPO_TEXTO == ((Figura)L.get(i)).getTipoFigura()){
                    selec = true;
                    L.set(i,Texto.ModificarTexto(null,((Texto)L.get(i))));
                    actualizar_paint();
                  }
              }             
            }
            if (selec == false){
                  Texto t = Texto.CrearTexto(null,p, creador);
                  if(t!=null)
                      L.add(0,t);
              }
            this.repaint();
        }
        if(creador.pincel == Figura.TIPO_CURVA && control_curva){
            ((Figura)L.get(0)).Elastico(e.getPoint());
            control_curva = false;
            this.repaint();
        }
        if(creador.pincel == Figura.TIPO_CURVA_2C && control_curva && control_curva2){
           ((Curva_2C)L.get(0)).Mod_1P_control(e.getPoint());
           control_curva = false;
           repaint();
        }else
            if(creador.pincel == Figura.TIPO_CURVA_2C && !control_curva &&control_curva2){
                ((Curva_2C)L.get(0)).Mod_2P_control(e.getPoint());
                control_curva2 = false;
                repaint();
            }
  }

  void mouseReleased(MouseEvent e) {
     if(creador.pincel == Figura.TIPO_CIRCULO ||
           creador.pincel == Figura.TIPO_RECTANGULO ||
           creador.pincel == Figura.TIPO_LINEA){
            ((Figura)L.get(0)).Elastico(e.getPoint());
            this.repaint();
     }else{
         if(creador.pincel == Figura.TIPO_CURVA && !control_curva){
              L.set(0, new Curva( ((Linea)L.get(0)) ));
              control_curva = true;
         }
         if(creador.pincel == Figura.TIPO_CURVA_2C && !control_curva && !control_curva2){
            ((Figura)L.get(0)).Elastico(e.getPoint());
            control_curva = true;
            control_curva2 = true;
         }
         this.repaint();
     }

  }

  void mousePressed(MouseEvent e) {
    p = e.getPoint();
    if(L.size() > 0 && !this.control_curva && !this.control_curva2){
        Graphics2D G = (Graphics2D) buffer.getGraphics();
        G.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        ((Figura)L.get(0)).Dibujar(G);
    }
    switch(creador.pincel){
        case Figura.TIPO_TRAZO:
          Trazo trazo = new Trazo(p,creador.stroke,creador.paint,creador.alfa);
          L.add(0,trazo);
          break;
        case Figura.TIPO_LINEA:
          Linea lin = new Linea(p,p,creador.stroke,creador.paint,creador.alfa);
          L.add(0,lin);
          break;
        case Figura.TIPO_CIRCULO:
          Circulo cir = new Circulo(p,p,creador.stroke,creador.paint,creador.B_relleno.isSelected(),creador.alfa);
          L.add(0,cir);
          break;
        case Figura.TIPO_RECTANGULO:
          Rectangulo rec = new Rectangulo(p,p,creador.stroke,creador.paint,creador.B_relleno.isSelected(),creador.alfa);
          L.add(0,rec);
          break;
        case Figura.TIPO_CURVA:
            if(!control_curva){
                Linea c = new Linea(p,p,creador.stroke,creador.paint,creador.alfa);
                L.add(0,c);
            }
          break;
        case Figura.TIPO_CURVA_2C:
          if(!control_curva && !control_curva2){
            Curva_2C curva_2c = new Curva_2C(p,p,p,p,creador.stroke,creador.paint,creador.alfa);
            L.add(0,curva_2c);
          }
          break;
        case Figura.TIPO_MOVER:
            if(seleccion != null){
                x = e.getX();
                y = e.getY();
            }
      }
  }

  void Motion_event(MouseEvent e) {
      if(creador.pincel != Figura.TIPO_MOVER){
            ((Figura)L.get(0)).Elastico(e.getPoint());
            this.repaint();
      }else{
          if(seleccion != null){
              ((Figura)L.get(indice_seleccion)).mover(e.getX()-x,e.getY()-y);
              seleccion.setFrame(seleccion.getX()+(e.getX()-x), seleccion.getY()+(e.getY()-y), seleccion.getWidth(), seleccion.getHeight());
              x = e.getX();
              y = e.getY();
              this.actualizar_paint();
          }
      }
}

  void moviendo_seleccion(MouseEvent e){
    if(creador.pincel == Figura.TIPO_MOVER){
        boolean selec = false;
        for(int i=0;i<L.size() && selec == false;i++){
          if(((Figura)L.get(i)).es_figura(e.getPoint())){
              seleccion = ((Figura)L.get(i)).rec_contenedor();
              selec = true;
              indice_seleccion = i;
          }
          if (selec == false)
              seleccion = null;
          this.repaint();
        }
    }else
        seleccion = null;
    if(creador.pincel == Figura.TIPO_CURVA && control_curva){
        ((Figura)L.get(0)).Elastico(e.getPoint());
        this.repaint();
    }else{
        if(creador.pincel == Figura.TIPO_CURVA_2C && control_curva && control_curva2){
            ((Curva_2C)L.get(0)).Mod_1P_control(e.getPoint());
            this.repaint();
        }else{
            control_curva = false;
            if(creador.pincel == Figura.TIPO_CURVA_2C && control_curva2){
                ((Curva_2C)L.get(0)).Mod_2P_control(e.getPoint());
                this.repaint();
            }else
                control_curva2 = false;
        }
    }

  }



    public void Combinar(){
        Graphics2D G = (Graphics2D) original.getGraphics();
        G.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        for(int i = 0; i<L.size();i++)
                    ((Figura)L.get(i)).Dibujar(G);
        buffer.getGraphics().drawImage(original, 0, 0, null);
        L.clear();
    }

    public BufferedImage get_original(){
        return original;
    }

    public BufferedImage get_imagen_combinada(){
        BufferedImage img = new BufferedImage(buffer.getWidth(),buffer.getHeight(),BufferedImage.TYPE_INT_RGB);
        Graphics2D G = (Graphics2D) img.getGraphics();
        G.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        G.drawImage(buffer, 0, 0, null);
        ((Figura)L.get(0)).Dibujar(G);
        return img;
    }


class Lienzo_this_mouseAdapter extends java.awt.event.MouseAdapter {
  Lienzo adaptee;

  Lienzo_this_mouseAdapter(Lienzo adaptee) {
    this.adaptee = adaptee;
  }
    @Override
  public void mouseClicked(MouseEvent e) {
    adaptee.this_mouseClicked(e);
  }
    @Override
  public void mouseReleased(MouseEvent e) {
    adaptee.mouseReleased(e);
  }
    @Override
  public void mousePressed(MouseEvent e) {
    adaptee.mousePressed(e);
  }
}

class Lienzo_this_mouseMotionAdapter extends java.awt.event.MouseMotionAdapter {
  Lienzo adaptee;

  Lienzo_this_mouseMotionAdapter(Lienzo adaptee) {
    this.adaptee = adaptee;
  }
    @Override
  public void mouseDragged(MouseEvent e) {
    adaptee.Motion_event(e);
  }

    @Override
  public void mouseMoved(MouseEvent e){
    adaptee.moviendo_seleccion(e);
  }
}



}




